package com.config.channels.controller;

import com.config.channels.entity.Channels;
import com.config.channels.entity.Version;
import com.config.channels.service.ChannelsService;
import com.config.channels.service.VersionService;
import com.config.channels.utils.Cryptos;
import com.config.channels.utils.MD5;
import com.config.channels.utils.ResObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @see com.config.channels.ChannelsApplication
 */
@Controller
public class ChannelsController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ChannelsService channelsService;

    @Autowired
    private VersionService versionService;

    @Value("${redirect.error.url}")
    private String errorUrl;

    //设置channels url 信息
    @ResponseBody
    @RequestMapping("/channels/setUrl")
    public ResObject setUrl(@RequestParam String id,
                            @RequestParam String url,
                            @RequestParam(required = false, defaultValue = "") String token) throws UnsupportedEncodingException {

        Channels channels = new Channels();
        channels.channelsId = id;
        channels.url = new String(Base64Utils.decodeFromUrlSafeString(url),"utf-8");
        channels.token = token;
        Channels save = channelsService.save(channels);

        return new ResObject();
    }



    //设置channels url 信息
    @RequestMapping("/channels")
    public void proxyUrl(@RequestParam String id,
                         @RequestParam String version,
                         @RequestParam String value,
                         HttpServletResponse response) throws IOException {
        try {
            String key = versionService.getAesKey(version);
            //解密字符串 key
            value = URLDecoder.decode(value,"utf-8");
            Map<String,String> ret = keyDecrypt(key,value);

            String nwtime = ret.get("nwtime");
            String imei = ret.get("imei");
            String mac = ret.get("mac");
            String sign = ret.get("sign");

            Long nwtimeTemp = new Date(Long.parseLong(nwtime)*1000L).getTime();
            Long nowTime = new Date().getTime();
            //如果nwtime和服务器上的时间相差超过5分钟，就判定这个url失效
            if(nowTime - nwtimeTemp >= 5*60*1000 || nowTime - nwtimeTemp <= -5*60*1000) {
                response.sendRedirect(errorUrl);
                return;
            }

            String s = id + imei + mac + key + nwtime;

            //校验sign
            if(sign.toUpperCase().equals(MD5.MD5Encode(s).toUpperCase())) {
               //Channels channels = channelsService.getByChannelsId(id);
                String url = channelsService.getUrl(id);
                response.sendRedirect(url);
                return;
            } else {
                response.sendRedirect(errorUrl);
                return;
            }

        } catch (Exception e) {
            //System.out.println(e.getMessage().toString());
            e.printStackTrace();
            response.sendRedirect(errorUrl);
        }
        return;
    }

    //解密字符串 key
    //imei=0123456789&mac=f0:00:01:02:03:04&nwtime=1522395470&sign=e633cacf27424535c7eed70c5e926d79
    private Map<String,String> keyDecrypt(String key,String value) {
        Cryptos cryptos = new Cryptos(key);
        String decryptStr = cryptos.aesDecrypt(value);
        String []  params = decryptStr.split("&");

        Map<String,String> ret = new HashMap<>();
        for(int i=0; i<params.length; i++) {
            String [] temp = params[i].split("=");
            ret.put(temp[0],temp[1]);
            //logger.info(String.format("key:%s<==>value:%s",temp[0],temp[1]));
        }
        return ret;
    }

    @RequestMapping("/channels/error")
    public String toError() {
        return "error";
    }

}
